package tripx.system;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * store the global configurations. including the connection setting to get
 * connection to the database server. and define how the server should be run.
 * 
 * @author zhb
 * 
 */
public class SysConfig {

	/**
	 * service mapping
	 */
	private PropertyHandlerMapping pMapping;
	/**
	 * configuration xml file
	 */
	private Document configDoc;
	/**
	 * server port, this program will listen
	 */
	private int serverPort;
	/**
	 * database service address.
	 */
	private String dbServerAddr;

	public SysConfig() {
		pMapping = new PropertyHandlerMapping();
		try {
			configDoc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(new File("./config/setup.xml"));
		} catch (SAXException | IOException | ParserConfigurationException e) {
			Logger.getInstance().err(
					"Errors Happen When Reading System Configuration File.");
			System.exit(-1);
		}
		initAll();
	}

	private void initAll() {
		Logger logger = Logger.getInstance();

		logger.info("Read Configuration Begins");
		Element root = configDoc.getDocumentElement();
		serverPort = Integer.parseInt(((Element) root.getElementsByTagName(
				"server").item(0)).getAttribute("port"));
		logger.info("\tServer Port: " + serverPort);
		dbServerAddr = ((Element) root.getElementsByTagName("db").item(0))
				.getAttribute("address");
		logger.info("\tDatabase Server Address: " + dbServerAddr);

		// add property handler mapping
		NodeList pmList = root.getElementsByTagName("handler");
		for (int i = 0; i < pmList.getLength(); i++) {
			Element e = (Element) pmList.item(i);
			try {
				logger.info("Add PropertyHandler: Key = "
						+ e.getAttribute("key") + ", Value = "
						+ e.getAttribute("class"));
				pMapping.addHandler(e.getAttribute("key"),
						Class.forName(e.getAttribute("class")));
			} catch (ClassNotFoundException | XmlRpcException e1) {

			}
		}
		logger.info("Read Configuration Ends");
	}

	public PropertyHandlerMapping getPropertyHandlerMapping() {
		return pMapping;
	}

	public int getServerPort() {
		return serverPort;
	}

	public String getDbServerAddr() {
		return dbServerAddr;
	}
}
